package utils;

import java.util.ArrayList;

import javax.swing.text.AbstractDocument.BranchElement;

import com.sun.xml.internal.ws.util.StringUtils;

import parser.Constants;
import parser.IupacBranch;
import parser.IupacRepeatTree;
import parser.IupacResidue;
import parser.IupacTree;
import parser.IupacUndCapTree;
import residue.Link;
import sugar.Stem;

public class TreeTools {



	static public IupacBranch getRootBranch(ArrayList<IupacBranch> tree) 
	{
		IupacBranch root=null;
		for (int i =0 ; i < tree.size() ; i++)
		{
			if(tree.get(i).getLevel()==0)
			{
				root = tree.get(i);
			}
		}
//		System.out.println("TreeTools getRootBranch Id: "+ root.getId());
	
		return root;
	}
	
	static public String getParentBranchId(IupacBranch branch)
	{
		String parentId="";
		String id = branch.getId();
		
		/*remove last character*/
		if(id.length()>=2)
		{
			parentId = id.substring(0, id.length()-1);
		}
//		System.out.println("TreeTools getParentBranchId : branch : "+ branch.getId() + ", parentId " + parentId);
		return parentId;
	}
	
	static public ArrayList<String> getChildrenBranchIds(IupacBranch branch, ArrayList<IupacBranch> tree)
	{
		ArrayList<String> childrenIds=new ArrayList<String>();
		String parentId = branch.getId();
		
		/*take every id containg the parent id which is longer by 1 char*/
		for(int i = 0; i < tree.size(); i++)
		{
			IupacBranch childBranch=tree.get(i);
			String childBranchId = childBranch.getId();
			
			//System.err.println("TEST : " + childBranchId.substring(0, -1));
			try
			{
				if(parentId.length()==1)
				{
//					System.out.println("TreeTools getChildrenBranchIds : parentId.length() " + parentId.length());
//					System.out.println("TreeTools getChildrenBranchIds : parentId.length() " + childBranchId.length());
					if(childBranchId.length()==2)
					{
						childrenIds.add(childBranchId);
//						System.out.println("TreeTools getChildrenBranchIds : branch : "+ branch.getId() + ", added childBranchId : " + childBranchId);
					}
				}
				//if(ParentId.length()>=2)
				else
				{
//					System.out.println("TreeTools getChildrenBranchIds : parentId.length() " + parentId.length());
//					System.out.println("TreeTools getChildrenBranchIds : childBranchId.length() " + childBranchId.length());
					
//					System.out.println("TreeTools getChildrenBranchIds : parentId " + parentId);
//					System.out.println("TreeTools getChildrenBranchIds : childBranchId " + childBranchId);
					
					String searchedParentId = childBranchId.substring(0, childBranchId.length()-1);
//					System.out.println("TreeTools getChildrenBranchIds : searchedParentId " + searchedParentId);
					
					if(searchedParentId.equals(parentId))
					{
						childrenIds.add(childBranchId);
//						System.out.println("TreeTools getChildrenBranchIds : branch : "+ branch.getId() + ", added childBranchId " + childBranchId);
					}
				}	
			}
			catch(Exception ex)
			{
				System.err.println("TreeTools getChildrenBranchIds : " + ex.getMessage());
				ex.printStackTrace();
			}
		}
		
		return childrenIds;
	}
	
	static public ArrayList<IupacBranch> getChildrenBranchesNotInSortedTree(IupacBranch parentBranch, ArrayList<IupacBranch> tree, ArrayList<IupacBranch> sortedTree)
	{
		ArrayList<IupacBranch> selectedChildren = new ArrayList<IupacBranch>();
		ArrayList<IupacBranch> children= getChildrenBranches(parentBranch, tree);
//		System.out.println("TreeTools getChildrenBranchesNotInSortedTree  : children.size() : "+ children.size());
		
		for(int i = 0; i<children.size();i++)
		{
			
			IupacBranch child = children.get(i);
//			System.out.println("TreeTools getChildrenBranchesNotInSortedTree  : child " +i+ " id : "+ child.getId());
			boolean test = isBranchInSortedTree(child, sortedTree);
//			System.out.println("TreeTools getChildrenBranchesNotInSortedTree before test : child " +i+ " id : "+ child.getId() + " test : "+ test);
			if(!test)
			{
//				System.out.println("TreeTools getChildrenBranchesNotInSortedTree  after !test : "+ child.getId() + ", added childBranchId " + child.getId() + " !test : "+ !test);
				selectedChildren.add(child);
			}	
		}
		
//		System.out.println("TreeTools getChildrenBranchesNotInSortedTree  array : " + arrayIdInLine(selectedChildren));
		
		return selectedChildren;
	}
	
	static public ArrayList<IupacBranch> getChildrenBranches(IupacBranch branch, ArrayList<IupacBranch> tree)
	{
		ArrayList<IupacBranch> children=new ArrayList<IupacBranch>();
		ArrayList<String> childrenIds = getChildrenBranchIds(branch, tree);
		
		for(int i = 0; i<childrenIds.size();i++)
		{
			children.add(getBranchFromBranchId(childrenIds.get(i), tree));
		}
		
		return children;
	}
	
	static public ArrayList<IupacBranch> getChildrenBranches(ArrayList<String> childrenIds, ArrayList<IupacBranch> tree)
	{
		ArrayList<IupacBranch> children=new ArrayList<IupacBranch>();
		
		for(int i = 0; i<childrenIds.size();i++)
		{
			children.add(getBranchFromBranchId(childrenIds.get(i), tree));
		}
		
		return children;
	}
	
//	static public IupacBranch getParentBranch(String parentId, ArrayList<IupacBranch> tree)
//	{
//		IupacBranch branch = getBranch(parentId, tree);
//		System.out.println("TreeTools getParentBranch from id : " + branch.getId());		
//		return branch;
//	}
	
	static public IupacBranch getParentBranch(IupacBranch branch, ArrayList<IupacBranch> tree)
	{

		String id = branch.getParentId();
//		System.out.println("TreeTools getParentBranch from branch : id : "+ id + ", tree.size() : " + tree.size());
	
		IupacBranch parentBranch =  getBranchFromBranchId(id, tree);
//		System.out.println("TreeTools getParentBranch from branch : parentBranch : "+  parentBranch.getId());
		
		return parentBranch;
	}
	
	static public IupacBranch getBranchFromBranchId(String branchId, ArrayList<IupacBranch> tree)
	{
		IupacBranch branch=null;
		int i=0;
		
		while(i<tree.size() && branch==null)
		{
			if(tree.get(i).getId().equals(branchId))
			{
				branch=tree.get(i);
//				System.out.println("TreeTools getBranch from id : "+ branch.getId());
				
			}
			i++;
		}
		return branch;
	}
	
	static public boolean hasChildrenBranches(IupacBranch branch, ArrayList<IupacBranch> tree)
	{
		boolean result=false;
//		System.out.println("TreeTools hasChildrenBranches branchId: "+ branch.getId() + " tree.size() : " + tree.size() + " " + result);

		ArrayList<String> childrenBranchIds = getChildrenBranchIds(branch,tree);
//		System.out.println("TreeTools hasChildrenBranches childrenBranchIds: "+ childrenBranchIds.get(0));

		if(!(childrenBranchIds.isEmpty()))
		{
			result = true;
		}
		
//		System.out.println("TreeTools hasChildrenBranches branchId: "+ branch.getId() + " " + result);

		return result;
	}
	
	static public boolean isBranchInSortedTree(IupacBranch branch, ArrayList<IupacBranch> sortedTree)
	{
		boolean result = false;
		
		for(int i = 0; i<sortedTree.size();i++)
		{
			if(branch.getId().equals((sortedTree.get(i).getId())))
			{
				result = true;
				
//				System.out.println("TreeTools isBranchInSortedTree branchId: "+ branch.getId() + " " + result);
//				System.out.println("TreeTools isBranchInSortedTree sortedTree.get(i).getId: "+ sortedTree.get(i).getId() + " " + result);
//				System.out.println("TreeTools isBranchInSortedTree sorted tree: "+ arrayIdInLine(sortedTree));				
			}
		}	
		return result;
	}
	static public String arrayIdInLine(ArrayList<IupacBranch> array)
	{
		String string = "";
		
		for(int j=0; j<array.size(); j++)
		{ 
			string += " "+array.get(j).getId();
		}
		return string;
	}
	static public IupacResidue getFirstResidue(IupacBranch branch)
	{
		return branch.getResidue(0);
	}
	
	static public IupacResidue getLastResidue(IupacBranch branch)
	{
		return branch.getResidue(branch.getResiduesList().size()-1);
	}
	
	static public IupacResidue getIdxResidue(IupacBranch branch, int idx)
	{
		return branch.getResidue(idx);
	}
	
	
	static public IupacResidue getPreviousResidue(int branchIdx, int residueIdx, ArrayList<IupacBranch> tree)
	{
		IupacResidue residue = null;
		IupacBranch parentBranch = null;
		
//		System.out.println("TreeTools getPreviousResidue currentResidue"+ branchIdx +","+residueIdx);
		try
		{
			//get previous abstractResidue on same branch if not first
			if(residueIdx > 0)
			{
				residue = tree.get(branchIdx).getResiduesList().get(residueIdx-1);
//				System.err.println("TreeTools getPreviousResidue on same branch : "+ (residueIdx-1));
			}
			else //or get the last abstractResidue of the parent branch
			{
				if(branchIdx > 0)
				{
				parentBranch = TreeTools.getParentBranch(tree.get(branchIdx).getId(),tree);
				int idx = parentBranch.getResiduesList().size()-1;
				
				residue = parentBranch.getResiduesList().get(idx);
				}
				else
				{
					
					residue = tree.get(0).getResiduesList().get(0);
//					System.err.println("TreeTools getPreviousResidue root : " +residue.getSequence());	
				}
			}
		}
		catch(Exception ex)
		{
			System.err.println("TreeTools getPreviousResidue " + ex.getMessage());	
		}
			
		return residue;
	}
	
	
	static public IupacResidue getPreviousResidue(IupacResidue res)
	{
		IupacResidue previousResidue = null;
		IupacBranch branch = null;
		ArrayList<IupacBranch> branches = null;
		
		int branchIdx = -1;
		int residueIdx = -1;
		
		try
		{
			
				branch = res.getBranch();
				branches = branch.getTree().getBranches();
				
				//search branch index in tree
				for (int i = 0; i<branches.size();i++)
				{
					if(branches.get(i).equals(branch))
					{
						branchIdx=i;
	//					System.out.println("TreeTools getPreviousResidue(res) currentResidue branch "+ branchIdx);
					}
				}
				//search IupacResidue index in branch
				for (int j = 0; j<branch.getResiduesList().size();j++)
				{
					if(branch.getResiduesList().get(j).equals(res))
					{
						residueIdx=j;
	//					System.out.println("TreeTools getPreviousResidue(res) currentResidue abstractResidue "+residueIdx);
					}
				}
//			if(!res.isTreeRoot()) 
//			{
		previousResidue = getPreviousResidue(branchIdx, residueIdx, branches);
//			}
		}
		catch(Exception ex)
		{
			System.err.println("TreeTools getPreviousResidue(res) " + ex.getMessage());	
		}

		return previousResidue;
	}
	
	static public IupacBranch getParentBranch(String branchId, ArrayList<IupacBranch> tree )
	{
		
		IupacBranch branch=null;
		String searchId = branchId;
		try
		{
			//if(branchId!="0")
			if(branchId.length()>1)
			{	
			searchId = branchId.substring(0, (branchId.length())-1 );
			}
//			System.out.println("TreeTools getParentBranch child id : "+ branchId);		
//			System.out.println("TreeTools getParentBranch searched id : "+ searchId);
			
			for(int i = 0; i<tree.size();i++)
			{
				
//				System.err.println("TreeTools getParentBranch id : "+ tree.get(i).getId());
				
				if(tree.get(i).getId().equals(searchId) && searchId != "0")
				{
					branch=tree.get(i);
//					System.out.println("TreeTools getParentBranch parent id : "+ tree.get(i).getId());
					return branch;
				}
			}
		}
		catch(Exception ex )
		{
			System.err.println("TreeTools getParentBranch ");
			ex.printStackTrace();	
		}
//		System.out.println("TreeTools getParentBranch parent id : "+ tree.get(i).getId());
		return branch;
	}
	
//	static public IupacBranch getParentBranch(String parentId, ArrayList<IupacBranch> tree)
//	{
//		IupacBranch branch = getBranch(parentId, tree);
//		System.out.println("TreeTools getParentBranch from id : " + branch.getId());		
//		return branch;
//	}
	
	static public IupacBranch getBranchFromResidueId(String residueId, ArrayList<IupacBranch> tree)
	{
		IupacBranch branch=null;
		int i=0;
		
		String branchId = residueId.substring(0,residueId.indexOf("."));
		while(i<tree.size() && branch==null)
		{
			
			if(tree.get(i).getId().equals(branchId))
			{
				branch=tree.get(i);
//				System.out.println("TreeTools getBranch from residueId : " + residueId + ", branchId : " + branch.getId());
				
			}
			i++;
		}
		return branch;
	}
	
	static public boolean hasRepeatChar(String sequence)
	{
		if(sequence.contains(Constants.openingCurlyBracket.toString()) || sequence.contains(Constants.closingCurlyBracket.toString()))
		{
//			System.out.println("TreeTools.hasRepeat() is TRUE: " + sequence);
			return true;
		}
//		System.out.println("TreeTools.hasRepeat() is FALSE: " + sequence);
		return false;
	}
	
	
	
	static public String getComment(String sequence)
	{
		String result = sequence.substring(sequence.indexOf(Constants.doubleQuote)); 
//		System.out.println("TreeTools.hasComment() is FALSE: " + sequence);
		return result;
	}
	
	static public boolean hasCommentChar(String sequence)
	{
		if(sequence.contains(Constants.doubleQuote.toString()))
		{
//			System.out.println("TreeTools.hasComment() is TRUE: " + sequence);
			return true;
		}
//		System.out.println("TreeTools.hasComment() is FALSE: " + sequence);
		return false;
	}
	
	static public boolean hasLinkage(String seq)
	{
		boolean result = false;
		
		if(seq.contains(Constants.openingParenthesis.toString()) && seq.contains(Constants.closingParenthesis.toString()))
		{
			result = true;
		}
		return result;
	}
	
	//get the multitude from a sequence for a repeat at given position and write to
	static public String getMultitude(String sequence, int ClosBracketPos) 
	{
//		System.out.println("getMultitude sequence : "+sequence);
		String result = "";
		char charMultitude;
		int i=1;
		
		while((ClosBracketPos+i)<sequence.length() && (Character.isDigit(sequence.charAt(ClosBracketPos+i)) || sequence.charAt(ClosBracketPos+i)==(Constants.DASH).charAt(0)))
		{
			charMultitude=sequence.charAt(ClosBracketPos+i);
			if(Character.isDigit(charMultitude) || sequence.charAt(ClosBracketPos+i)==(Constants.DASH).charAt(0))
			{
				result += charMultitude;
			}
			i++;
		}	
//		System.out.println("getMultitude sequence : "+result);
		if(result =="")
		{
			result = "1";
		}
		return result;
	}
	
	
	//get the multitude from a sequence for a repeat at given position and write to
	static public int[] getMultitudeMinMax(String MultitudeSequence) 
	{
		int[] minmax = new int[2];
//		Integer.parseInt(multitude)	
		String tempValue ="";
		int seqIdx=0;
		int vectIdx=0;
		
//		System.err.println(" getMultitudeMinMax input "+MultitudeSequence);
		while(seqIdx<MultitudeSequence.length())
		{
			
			if(Character.isDigit(MultitudeSequence.charAt(seqIdx)))
			{
				tempValue += MultitudeSequence.charAt(seqIdx);
//				System.err.println(" getMultitudeMinMax1 "+tempValue);
			}
			//if explicit max
			if(MultitudeSequence.charAt(seqIdx)==(Constants.DASH).charAt(0)) 
			{
				minmax[vectIdx]=Integer.parseInt(tempValue);
				vectIdx++;
				tempValue="";
//				System.err.println(" getMultitudeMinMax2 "+tempValue);
			}	
//			System.err.println(" getMultitudeMinMaxIdx : "+seqIdx + " vectidx "+vectIdx );
			seqIdx++;
			
		}	
		//register value if min only (without max) or max
		minmax[vectIdx]=Integer.parseInt(tempValue);
//		System.err.println(" getMultitudeMinMaxInt "+minmax[vectIdx] + " ; " + vectIdx);
		
		//check if max exists, otherwise max = min
		if(vectIdx==0)
		{
			minmax[1]=minmax[0];
		}		
//		System.err.print(" getMultitudeMinMax "+minmax[0]+" "+minmax[1]);
		return minmax;
	}
	
	
	static public String removeBrackets(String seq)
	{
		String s = seq;
		if(seq.length()>0)
		{
			s=seq.substring(1,seq.length()-1);
//		System.out.println("TreeTools.removeBrackets() s : "+s);
		}
		return s;
	}
//	static public String removeEmmbeddingChar(String seq)
//	{
//		String s = seq.substring(1,seq.length()-1);
//		return s;
//	}
	
	static public boolean isRepeatSequence(String seq)
	{
		boolean result = false;
		
		if(seq.contains(Constants.openingCurlyBracket.toString()) && seq.contains(Constants.closingCurlyBracket.toString()))
		{
			result = true;
		}
		return result;
	}
	
	public static ArrayList<IupacResidue> getAllMonosaccharides(IupacTree tree)
	{
		
		ArrayList<IupacResidue> monosaccharides = new ArrayList<IupacResidue>();
		if(!tree.isUndCapTree())
		{
//		System.err.println("Treetools getAllMonosaccharides tree : " + tree.getSequence());				
//		System.err.println("Treetools getAllMonosaccharides branches size : " + tree.getBranches().size());				
		
		for(int i =0;i<tree.getBranches().size();i++)
		{			
			IupacBranch branch = tree.getBranches().get(i);
//			System.err.println("Treetools getAllMonosaccharides branch id : " + branch.getId());				
			
			for(int j=0;j<branch.getResiduesList().size();j++)
			{
				IupacResidue residue = branch.getResiduesList().get(j);
//				System.err.println("Treetools getAllMonosaccharides residue id : " + residue.getId());				
				if(residue.getAbstractResidue().isGenericMonosaccharideResidue())
				{
//					System.err.println("Treetools getAllMonosaccharides monosaccharide id : " + residue.getId());				
					monosaccharides.add(residue);
				}
			}
			
		}
		}
//		System.err.println("Treetools getAllMonosaccharides size : " +monosaccharides.size());
		return monosaccharides;
		
	}
	
	public static String UndMultitudeCheck(String seq)
	{
		System.out.println("UndMultitudeCheck :"+seq);
		if(seq!=null && seq.length()!=0)
		{
			String regex = "(?i)([0-9])x.*"; //multitude like 2x			
			if(!(seq.matches(regex)))
			{
				seq="1x"+seq;
			}
		}	
		return seq;
	}
	
	public static ArrayList<IupacUndCapTree> parseUndCapSeqAndMultitude(String partialSequence, IupacTree t)
	{
		partialSequence=cleanComment(partialSequence);
		partialSequence=partialSequence.trim();
		partialSequence=UndMultitudeCheck(partialSequence);			
		
		
		int xPos = 0;
		int multitude = 1;
		String seq = "";
		ArrayList<IupacUndCapTree> undcaps = new ArrayList<IupacUndCapTree>();
		
		System.out.println("UND seq part :" + partialSequence);
		//define x pos to split and get sequence and multiplier
		if(partialSequence!=null && partialSequence.length()!=0)
		{
			xPos = findXPos(partialSequence);
			if(xPos==0)
			{
				seq=partialSequence;
			}
		}
		System.out.println(" xpos "+xPos);
		//split by x or X and not Xyl or Hex or Lyx		
		if(xPos!=0)
		{
			System.out.println(" xpos !=0 "+partialSequence.substring(0,xPos));
			multitude = Integer.valueOf(partialSequence.substring(0,xPos));
			seq = partialSequence.substring(xPos+1).trim();	
			
			System.out.println("UND seq mult: " + multitude);
			System.out.println("UND seq sequence: " + seq);
		}
		
		for(int i=0; i<multitude ; i++)
		{
			if(seq.length()!=0)
			{
				IupacUndCapTree und = new IupacUndCapTree(checkFirstLinkage(seq));
				System.out.println(i + " IupacUndCapTree seq " + checkFirstLinkage(seq));
				und.setParentTree(t);
				undcaps.add(und);
			}
		}
		
		return undcaps;
	}
	
	
	public static int findXPos(String s)
	{
		int pos=0;
		try
		{
			//find the first x to get the multiplier ex : 2xNeuAc(?1-5)
			int temp=s.toUpperCase().indexOf(Constants.UNKNOWN.toUpperCase());
			String tempSeq = s.substring(temp, temp+2);
			System.out.println("TreeTools findXPos() : " + s);
			System.out.println("TreeTools findXPos() : " + temp);
			
			if(Stem.fromString(tempSeq)==null)
			{
				pos=temp;
				System.out.println("OK " + pos);
			}
			else
			{	
				return findXPos(s.substring(temp+1));
			}
		}
		catch(Exception ex)
		{
//			System.err.println("TreeTools findXPos()" + ex.getMessage());
		}
		
		return pos;
	}
	
	/*Remove space, plus and doublequote*/
	static public String cleanComment(String sequence)
	{
//		System.err.println("TreeTools cleanComment()");
		
		String result = sequence;
//		System.out.println("cleanComment : "+ result);
		result = result.replaceAll("\\+", "");
		result = result.replaceAll("\"", "");
		result = result.replaceAll("\\s", "");
		
		try
		{
			if(result!=null && result.length()!=0)
			{
	//			System.out.println("cleanComment between parenthesis");
				if(result.charAt(0) == (Constants.openingParenthesis) && result!=null && result.length()!=0)
				{
					System.out.println("cleanComment between parenthesis");
					result = TreeTools.removeBrackets(result);
				}
			}
		}
		catch(Exception ex)
		{
			System.err.println("TreeTools cleanComment()" + ex.getMessage());
		}
		
		
//		System.out.println("cleanComment : "+ result);
		return result;
	}
	
	static public String checkFirstLinkage(String sequence)
	{
		String result = "";
		
		if(!(hasLinkage(sequence) && sequence.charAt(sequence.length()-1)==Constants.closingParenthesis))
		{
			result = addSequenceLinkage(sequence);
//			System.out.println("checkFirstLinkage added : " + result);
		}
		else
		{
			result = sequence;
//			System.out.println("checkFirstLinkage NOT added : " + result);
		}
			
		return result;
	}
	
	static public String repeatValidForm(String multitude, String sequence)
	{
		String result = "";
		int multitudeMax = getMultitudeMinMax(multitude)[1];
		
		result = checkFirstLinkage(sequence);
//		System.err.println("repeatValidForm before : " + sequence);
//		System.err.println("repeatValidForm after : " + result);
		//if >=7 write as repetition, else expand 
		if(multitudeMax >=7)
		{
			result = Constants.openingCurlyBracket + result + Constants.closingCurlyBracket + multitude;
//			System.out.println("repeatValidForm > 7 : " + result);
		}
		else
		{
			result = expandRepeat(multitudeMax, result);
		}	
		return result;
	}
	
	static public String addSequenceLinkage(String sequence)
	{
		return sequence + Constants.UNKNOWN_IUPAC_LINKAGE;
	}
	
	static public String expandRepeat(int multitude, String sequence)
	{
		String result = "";
		for(int i = 0; i<multitude; i++)
		{
			result += sequence;
		}
		
		return result;
	}
	
	static public IupacTree getTopTreeRepeat(IupacTree tree) {
		
		
		IupacRepeatTree repeat = new IupacRepeatTree("");

//		System.err.println("getTopTree type : "+ tree.getClass().getName());
		
		//if tree is a IupacRepeatTree, recurse, else return tree
		if((tree.getClass().getName().equals(repeat.getClass().getName())))
		{	
//			System.err.println("getTopTree IupacRepeatTree : "+((IupacRepeatTree)tree).getResidue());
			return ((IupacRepeatTree)tree).getResidue().getBranch().getTree();
			
		}
		else 
		{
//			System.err.println("getTopTree IupacTree : "+tree);
			return tree;
		}
	}
	
	static public IupacResidue getFirstSubtreeResidue(IupacTree tree)
	{
		IupacResidue res = tree.getBranches().get(0).getResidue(0);
//		System.err.println("getFirstResidue : " + res.getSequence() + " : "+ res.getId());
		return res;
	}
	
	static public IupacResidue getLastSubtreeResidue(IupacTree tree)
	{
		IupacBranch branch = tree.getBranches().get(tree.getBranches().size()-1);
		IupacResidue res = branch.getResidue(branch.getResiduesList().size()-1);
//		System.err.println("getLastResidue : " + res.getSequence() + " : "+ res.getId());
		return res;
	}
	
	static public IupacResidue removeAglyconRoot(IupacResidue residue)
	{
		if(!residue.getAbstractResidue().isGenericMonosaccharideResidue() && !residue.getAbstractResidue().isGenericRepeatResidue()&& !residue.getAbstractResidue().isGenericComposedResidue() && residue.isTreeRoot())
		{
			System.out.println("Root residue "+residue.getAbstractResidue().toString()+" is aglycon and is removed from GlycoCT");
			residue=null;
		}		
		return residue;
	}
}
